<?php

/*
	Experimental tool for generating Doctrine models from Yaml files.
	This program was not revised for the newest version of Doctrine and so it is considered as experimental.
*/


$ds = DIRECTORY_SEPARATOR;
$recordsPath = dirname(dirname(__FILE__)) . "{$ds}library{$ds}Application{$ds}Db{$ds}:dbName{$ds}Record";
$ymlFilesPath = dirname(dirname(__FILE__)) . "{$ds}library{$ds}Application{$ds}Db{$ds}:dbName{$ds}Record{$ds}Yml";


require_once('includes.php');
require_once('Doctrine.php');
spl_autoload_register(array('Doctrine', 'autoload'));

$dmg = new DoctrineModelsGenerator();
echo "0%\n";

$ymlFiles = $dmg->searchYamlFiles($ymlFilesPath);
echo "This yml files were found: (20%)\n";
print_r($ymlFiles);

$dmg->createYamlJoinFile($ymlFiles, $ymlFilesPath);
echo "Yaml join file successfuly created. (40%)\n";

$dmg->generateModelsFromYaml("." . DIRECTORY_SEPARATOR . DoctrineModelsGenerator::DEFAULT_JOIN_FILE, $recordsPath);
echo "Models successfuly generated. (80%)\n";

$dmg->renamePrefixedModelFiles($recordsPath);
echo "Models successfuly renamed. (100%)\n";


class DoctrineModelsGenerator
{
    const DEFAULT_JOIN_FILE = "_joinFile.yml";
    
    public static function searchYamlFiles ($directory, $pattern = null)
    {
        $directory = rtrim($directory, "\\/");
        
        if ($pattern === null) {
          // zjistí všechny yml soubory, které nezačínají podtržítkem
          $pattern = '/^[^_].*\.yml$/';
        }
        $paths=array();
        $dh = opendir($directory);
        while ($file = readdir($dh)) {
            if (preg_match($pattern, $file)) {
                $paths[] = $directory . DIRECTORY_SEPARATOR . $file;
            }
        }
        
        return $paths;
    }
    
    public static function createYamlJoinFile (array $yamlFiles, $targetDir, $yamlJoinFileName = null)
    {    
        $targetDir = rtrim($targetDir, "\\/");
        if ($yamlJoinFileName === null) {
            $yamlJoinFileName = self::DEFAULT_JOIN_FILE;
        }
        
        $jfContent = "";        
        foreach ($yamlFiles as $yamlFile) {
            if (!is_string($yamlFile)) {
                throw new Exception('Only array of strings may be passed as 1st argument');
            }
            
            $fh = fopen($yamlFile, 'r');
            if (!$fh) {
                
                throw new Exception('Error opening yml file.');
            }
            $content = fread($fh, filesize($yamlFile));
            $jfContent .= trim($content) . "\r\n";
            fclose($fh);
        }
        $jfh = fopen($targetDir . DIRECTORY_SEPARATOR . $yamlJoinFileName, 'w');
        if (!$jfh) {
            throw new Exception('Error creating the join file.');
        }
        fwrite($jfh, $jfContent);
        fclose($jfh);
        
        return $jfContent;
    }
    
    public static function generateModelsFromYaml ($yamlFilePath, $targetPath, array $options = array())
    {
        $targetPath = rtrim($targetPath, "\\/");
        $defaultOptions = array(
          //'packagesPrefix'        =>  'Package',           // What to prefix the middle package models with
          //'packagesPath'          =>  '',                  // this defaults to the "#models_path#/packages"
            'generateBaseClasses'   =>  false,                  // Whether or not to generate abstract base models containing the definition and a top level class which is empty extends the base
            'generateTableClasses'  =>  true,                  // Whether or not to generate a table class for each model
          //'baseClassesDirectory'  =>  'Base',                // Name of the folder to generate the base class definitions in
          //'baseClassName'         =>  'Doctrine_Record',     // Name of the base Doctrine_Record class
            'suffix'                =>  '.php',                // Extension for your generated models
            'targetPath' => $targetPath
        ); 
        
        $options = array_merge($defaultOptions, $options);
        Doctrine::generateModelsFromYaml($yamlFilePath, $targetPath, $options);
    }
        
    public static function renamePrefixedModelFiles ($directory, $pattern = null, $replacement = null)
    {
        if ($pattern === null) {
            $pattern = '/^.+_([^_]+)\.php$/i';
        }
        if ($replacement === null) {
            $replacement = '$1.php';
        }
        $ds = DIRECTORY_SEPARATOR;
        
        $directory = rtrim($directory, "\\/");
        $dh = opendir($directory);
        while ($fileName = readdir($dh)) {
            if (preg_match($pattern, $fileName)) {
                $newFileName = preg_replace($pattern, $replacement, $fileName);
                
                $newFileNamePath = $directory . $ds . $newFileName;
                if (file_exists($newFileNamePath)) {        
                    unlink($newFileNamePath);
                }
                rename($directory . $ds . $fileName, $newFileNamePath);
            }
        }
        closedir($dh);
    }
}
